package com.syp.envops.service.impl;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.syp.envops.dao.ServerMapper;
import com.syp.envops.domain.ConfigStateEnum;
import com.syp.envops.domain.ConfigTypeEnum;
import com.syp.envops.domain.pojo.ServerSchema;
import com.syp.envops.domain.vo.ConfigVo;
import com.syp.envops.service.ConfigServiceI;
import com.syp.envops.util.sftp.ExtnameExcludeFilter;
import com.syp.envops.util.sftp.Filter;
import com.syp.envops.util.sftp.SftpClient;
import com.syp.envops.util.sftp.SftpConfiguration;
import com.syp.envops.util.sftp.SftpFile;

@Service("configService")
public class ConfigServiceImpl implements ConfigServiceI {

	@Autowired
	private ServerMapper serverMapper;

	@Override
	public List<SftpFile> list(int serverId, String path, boolean recursive) {
		ServerSchema ss = serverMapper.getById(serverId);
		SftpConfiguration sftpConfiguration = new SftpConfiguration(ss);
		SftpClient sftpClient = new SftpClient(sftpConfiguration);

		if (ss.getFilter() != null && !ss.getFilter().isEmpty()) {
			String[] filterStrings = ss.getFilter().split(";");
			List<String> extnameExcludeList = Arrays.asList(filterStrings);
			Filter filter = new ExtnameExcludeFilter(extnameExcludeList);
			return sftpClient.list(path, filter, false);
		} else {
			return sftpClient.list(path, false);
		}
	}

	@Override
	public SftpFile get(int serverId, String absolutePath) {
		ServerSchema ss = serverMapper.getById(serverId);
		SftpConfiguration sftpConfiguration = new SftpConfiguration(ss);
		SftpClient sftpClient = new SftpClient(sftpConfiguration);

		return sftpClient.get(absolutePath);
	}

	@Override
	public void save(int serverId, String absolutePath, byte[] content) {
		try {
			ServerSchema ss = serverMapper.getById(serverId);
			SftpConfiguration sftpConfiguration = new SftpConfiguration(ss);
			SftpClient sftpClient = new SftpClient(sftpConfiguration);

			sftpClient.upload(absolutePath, content);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void rm(int serverId, String absolutePath, boolean isDir) {
		ServerSchema ss = serverMapper.getById(serverId);

		SftpConfiguration sftpConfiguration = new SftpConfiguration(ss);
		SftpClient sftpClient = new SftpClient(sftpConfiguration);
		if (isDir) {
			sftpClient.rmdir(absolutePath);
		} else {
			sftpClient.rm(absolutePath);
		}
	}

	@Override
	public void transform(SftpFile sftpFile, int level, LinkedList<ConfigVo> dest) {
		ConfigVo config = new ConfigVo();

		config.setId(UUID.randomUUID().toString());
		config.setLevel(level);
		Integer[] passLevels = new Integer[level];
		for (int i = 1; i <= level; i++) {
			passLevels[i - 1] = i;
		}
		config.setPassLevels(passLevels);
		config.setServerId(sftpFile.getServerId());
		config.setUsername(sftpFile.getUsername());
		config.setHost(sftpFile.getHost());
		int lastIndexOfdolt = sftpFile.getFilename().lastIndexOf(".");
		String ext = "";
		if (lastIndexOfdolt > -1) {
			ext = sftpFile.getFilename().substring(lastIndexOfdolt);
		}
		ConfigTypeEnum configType = ConfigTypeEnum.getEnum(ext);
		config.setConfigType(configType.getCode());
		config.setFilename(sftpFile.getFilename());
		config.setAbsolutePath(sftpFile.getAbsolutePath());
		config.setFileLen(sftpFile.getFileLen());
		config.setCreateTime(sftpFile.getCreateTime());
		config.setLastUpdate(sftpFile.getLastUpdate());
		config.setIsDir(sftpFile.getIsDir());
		
		if (sftpFile.getIsDir()) {
			config.setState(ConfigStateEnum.CLOSE.getState());
		} else {
			config.setState(ConfigStateEnum.NONE.getState());
		}

		dest.add(config);
		if (sftpFile.getChildren() != null && !sftpFile.getChildren().isEmpty()) {
			for (SftpFile sub : sftpFile.getChildren()) {
				this.transform(sub, level + 1, dest);
			}
		}
	}

	@Override
	public LinkedList<ConfigVo> transform(List<SftpFile> sftpFileList, int plevel) {
		LinkedList<ConfigVo> dest = new LinkedList<ConfigVo>();
		for (SftpFile item : sftpFileList) {
			this.transform(item, plevel + 1, dest);
		}
		return dest;
	}

	@Override
	public void mkDir(int serverId, String absolutePath) {
		try {
			ServerSchema ss = serverMapper.getById(serverId);
			SftpConfiguration sftpConfiguration = new SftpConfiguration(ss);
			SftpClient sftpClient = new SftpClient(sftpConfiguration);

			sftpClient.mkDir(absolutePath);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void uploadFile(int serverId, String path, MultipartFile multipartFile) {
		try {
			ServerSchema ss = serverMapper.getById(serverId);
			SftpConfiguration sftpConfiguration = new SftpConfiguration(ss);
			SftpClient sftpClient = new SftpClient(sftpConfiguration);

			String configPath = path + "/" + multipartFile.getOriginalFilename();
			sftpClient.upload(configPath, multipartFile.getBytes());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
